const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const defaultIgnorePackages = ["npm-packs"];

// 找出node_modules中所有需要打包的文件根路径
function findNodeModulesAllPacksPath(){
    const allPacksPath = []
    const node_modules = path.join(process.cwd(), "node_modules");
    const dirs = getDirChildren(node_modules,defaultIgnorePackages);
    dirs.forEach((dir) => {
        const modulePath = path.join(node_modules, dir);
        if(dir.startsWith("@")){
            const atDir = getDirChildren(modulePath)
            atDir.forEach((aDir) => {
                const aModelPath = path.join(modulePath,aDir);
                allPacksPath.push(aModelPath);
            })
        }else{
            allPacksPath.push(modulePath);
        }
    })

    return allPacksPath;
}


/**
 *  获取文件夹下所有文件夹
 * @param {string} pathDir 文件夹路径
 * @param {Array[string]} ignoreDir 要排除的文件夹
 * */
function getDirChildren(pathDir,ignoreDir = []){
    return fs.readdirSync(pathDir).filter((dir) => {
        return !dir.startsWith(".") && !ignoreDir.includes(dir);
    })
}


/**
 * 指定一个项目路径，打包
 * @param {string} pathDir 要打包的项目路径
 * @param {string} outPath 输出路径
 * @returns {Promise<{success: boolean, message: string}>}
 */
function packModule(pathDir, outPath) {
    return new Promise((resolve, reject) => {
        try {
            // 执行 npm pack 命令
            const output = execSync("npm pack", {
                cwd: pathDir,
                stdio: ['ignore', 'pipe', 'ignore']
            }).toString().trim();

            const tgzFileName = output.split("\n").pop();
            const tgzFilePath = path.join(pathDir, tgzFileName);
            const destinationPath = path.join(outPath, tgzFileName);

            // 检查文件是否存在
            if (!fs.existsSync(tgzFilePath)) {
                return resolve({
                    success: false,
                    message: `No tgz file generated in ${pathDir}`
                });
            }

            // 确保输出目录存在
            if (!fs.existsSync(outPath)) {
                fs.mkdirSync(outPath, { recursive: true });
            }

            // 移动文件
            fs.renameSync(tgzFilePath, destinationPath);

            resolve({
                success: true,
                message: `Moved ${tgzFileName} to ${outPath}`
            });

        } catch (e) {
            console.log(`Requesting Internet for ${pathDir}...`);

            // 读取 package.json
            fs.readFile(path.join(pathDir, 'package.json'), 'utf8', (err, data) => {
                if (err) {
                    return resolve({
                        success: false,
                        message: `Error reading package.json in ${pathDir}: ${err.message}`
                    });
                }

                try {
                    const packageJson = JSON.parse(data);
                    // 调用网络下载函数（也需要返回 Promise）
                    packInterModel(packageJson.name, packageJson.version, outPath)
                      .then(result => resolve(result))
                      .catch(err => resolve({
                          success: false,
                          message: `Error downloading package: ${err.message}`
                      }));
                } catch (parseErr) {
                    resolve({
                        success: false,
                        message: `Error parsing package.json in ${pathDir}: ${parseErr.message}`
                    });
                }
            });
        }
    });
}

/**
 * 尝试从网络下载包 (Promise 版本)
 * @param {string} packName 包名
 * @param {string} version 版本号
 * @param {string} outdir 输出目录
 * @returns {Promise<{success: boolean, message: string}>}
 */
function packInterModel(packName, version, outdir) {
    return new Promise((resolve) => {
        const packA = `${packName}@${version}`;
        try {
            execSync("npm pack " + packA, {
                cwd: outdir,
                stdio: ['ignore', 'pipe', 'ignore']
            });
            resolve({
                success: true,
                message: `Downloaded ${packA} successfully`
            });
        } catch (e) {
            console.log(packA, '下载失败');
            fs.appendFileSync(path.join(outdir, 'error.log'), `${packA}下载失败！\n`, 'utf8');
            resolve({
                success: false,
                message: `Failed to download ${packA}`
            });
        }
    });
}

module.exports = {
    getDirChildren,
    findNodeModulesAllPacksPath,
    packModule
}